﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using XZen.Cdn.Client.Authentications;
using XZen.Cdn.Client.Blobs;
using System.ServiceModel.Channels;
using System.ServiceModel;
using System.Runtime.Caching;

namespace XZen.Cdn.Client
{
    public abstract  class ContentClient
    {
        public abstract ContentSetting AppSettings { get; set; }
        AuthenticationServiceClient _membership;
        BlobServiceClient _client;
        MemoryCache _store = new MemoryCache("URL-MAP");
        
        string _contentUri = "http://cdn.ipatrika.com";
        string _token = "";
        int _language = 0;
        int cacheDurationInSeconds = 60 * 60;
       
        static bool IsLoggedIn = false;
        bool IsSettingsApplied = false;
        public ContentClient()
        {
        }
        public ContentClient(string contentUri)
        {
            _contentUri = contentUri;
        }
       
        public string Language
        {
            get
            {
                _language = LanguageCode.ENGLISH_LANG;
                return _language.ToString();
            }
        }
        public string Token
        {
            get
            {
                if (IsLoggedIn == false)
                {
                    Login();
                }
                if (string.IsNullOrWhiteSpace(_token))
                {
                    _token = Client.SetKeyValueContext(_contentUri);
                }
                return _token;
            }
            set { _token = value; }
        }
        public BlobServiceClient Client
        {
            get
            {
                if (IsSettingsApplied == false)
                    ApplySettings();
                return _client;
            }
        }

        public bool Login()
        {
            System.Net.ServicePointManager.Expect100Continue = false;
            if (!IsLoggedIn)
            {
                IsLoggedIn = _membership.IsLoggedIn();
            }
            if (!IsLoggedIn)
            {
                IsLoggedIn = _membership.Login(AppSettings.UserName, AppSettings.Password, string.Empty, true);
            }
            return IsLoggedIn;
        }
        public void ApplySettings()
        {
            BasicHttpBinding basic = new BasicHttpBinding();
            basic.MaxReceivedMessageSize = 10485760;
            EndpointAddress authEndpoint = new EndpointAddress(AppSettings.AuthenticationService);
            EndpointAddress blobEndpoint = new EndpointAddress(AppSettings.BlobService);
            CookieManagerEndpointBehavior behave = new CookieManagerEndpointBehavior();
            _membership = new AuthenticationServiceClient(basic, authEndpoint);
            _client = new BlobServiceClient(basic, blobEndpoint);
            _membership.Endpoint.Behaviors.Add(behave);
            _client.Endpoint.Behaviors.Add(behave);
            Login();
            IsSettingsApplied = true;
        }
        /// <summary>
        /// Public Library
        /// </summary>
        /// <param name="uri"></param>
        /// <returns></returns>
        public virtual Contents GetContents(string uri)
        {
            Contents xml;
            _contentUri = uri;
            var entry = _store.GetCacheItem(uri);
            if (entry == null)
            {
                string[] segments = uri.Split('#');
                string languageSegmentUri = uri;
                if (segments.Length != 2)
                {
                    languageSegmentUri = uri + "#" + Language;
                }
                var keyvalues = Client.GetKeyValuesByUri(uri, Token);
                xml = new Contents(keyvalues, Language);
                _store.AddOrGetExisting(uri, xml, new CacheItemPolicy()
                {
                    AbsoluteExpiration = new DateTimeOffset(DateTime.Now.AddSeconds(cacheDurationInSeconds))
                });
                return xml;
            }
            else
            {
                return entry.Value as Contents;
            }
        }

        /// <summary>
        /// Not very performance oriented.
        /// </summary>
        /// <param name="keyName"></param>
        /// <param name="url"></param>
        /// <returns></returns>
        public virtual string GetValueFromKey(string keyName, string url)
        {
            Contents contents = GetContents(url);
            string val = contents.GetValueFromKey(keyName);
            return val;
        }
        public virtual string GetValue(string keyName)
        {
            string val = GetValueFromKey(keyName, _contentUri);
            return val;
        }      
    }
    
    public static class LanguageCode
    {
        public static readonly int ENGLISH_LANG = 2057;
    }
}